package com.imay.live.helper;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;

import com.imay.live.IMApplication;

import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;

/**
 * Created by jeaman on 2017/4/19.
 */

public class LocationHelper implements LocationListener {
    private static LocationHelper instance;
    private Context mContext;

    private LocationManager mLocationManager;
    private Set<OnLocationListener> mLocationListenerSet = new HashSet<>();

    private String city = "";
    private double latitude;
    private double longitude;

    private LocationHelper() {
        mContext = IMApplication.getInstance();
    }

    public synchronized static LocationHelper getInstance() {
        if (instance == null) {
            instance = new LocationHelper();
        }
        return instance;
    }

    private void initLocationManager() {
        if (mLocationManager == null) {
            mLocationManager = (LocationManager) mContext.getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        }
        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        if (mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
            mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
        } else if (mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        }
    }

    public void getLocation(OnLocationListener listener) {
        synchronized (mLocationListenerSet) {
            initLocationManager();
            if (listener != null) {
                mLocationListenerSet.add(listener);
            }
        }
    }

    /**
     * 根据经纬度获取地理位置
     *
     * @param latitude  纬度
     * @param longitude 经度
     * @return {@link Address}
     */
    private Address getAddress(double latitude, double longitude) {
        Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());
        try {
            List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
            if (addresses.size() > 0) return addresses.get(0);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据经纬度获取所在地
     *
     * @param latitude  纬度
     * @param longitude 经度
     * @return 所在地
     */
    private String getLocality(double latitude, double longitude) {
        Address address = getAddress(latitude, longitude);
        return address == null ? "" : address.getLocality();
    }

    @Override
    public void onLocationChanged(final Location location) {
        if (mLocationManager == null) {
            mLocationManager.removeUpdates(this);
        }
        ThreadManager.post(ThreadManager.THREAD_BACKGROUND, new Runnable() {
            @Override
            public void run() {
                String city = getLocality(location.getLatitude(), location.getLongitude());
                synchronized (mLocationListenerSet) {
                    Iterator<OnLocationListener> iterator = mLocationListenerSet.iterator();
                    while (iterator.hasNext()) {
                        OnLocationListener listener = iterator.next();
                        listener.onLocation(city, location.getLatitude(), location.getLongitude());
                        iterator.remove();
                    }
                }
            }
        });
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public interface OnLocationListener {
        void onLocation(String city, double latitude, double longitude);
    }
}
